/*
 * UdpSession.cpp
 *
 *  Created on: 27/08/2011
 *      Author: george
 */

#include "udpsession.h"
#include <sstream>
#include <iostream>
#include <fstream>
#include "defines.h"
#include <arpa/inet.h>
#include <netinet/in.h>
#include <cstdlib>

#include <sys/time.h>

#include "info.h"

using namespace std;

UdpSession::UdpSession(struct in_addr src, struct in_addr dst, u_int16_t src_port, u_int16_t dst_port, u_int8_t protocol){

	std::ofstream packets;

	Info::getInstance()->nmUdpSessions++;

	timeval time;
	this->src_port = src_port;
	this->dst_port = dst_port;

	this->src = src;
	this->dst = dst;

	this->protocol = (u_int8_t)protocol;

//	Nome legivel da origem e destino da sessao icmp
	this->srcaddr = inet_ntoa(this->src);
	this->dstaddr = inet_ntoa(this->dst);

//	Para gerar o protocolo, porta de origem e destino como string
	stringstream protocol_name;

//	O o timestamp é utilizando para não termos dois arquivos com o mesmo nome para seçoes diferentes
	stringstream timestam_name;
	gettimeofday(&time, 0);
	timestam_name << time.tv_usec;

	stringstream src_port_name;
	stringstream dst_port_name;

	this->protocol_name << dec << this->protocol;
	this->src_port_name << dec << this->src_port;
	this->dst_port_name << dec << this->dst_port;

	this->filename = "udp-" + this->srcaddr  + ":" + this->src_port_name.str()  + "-" + this->dstaddr + ':' + this->dst_port_name.str() + "-" + this->protocol_name.str() + "-" + timestam_name.str() + ".xml";

	this->packets.open(this->filename.c_str(), ofstream::app);

	if ( !this->packets.is_open()){
		cout << "Erro ao abrir o arquivo " << this->filename << endl;
	}

	this->packets << "<udpsession src='" + this->srcaddr + "' dst='" + this->dstaddr + "' src_port='" + this->src_port_name.str() + "' dst_port='" + this->dst_port_name.str() + "' protocol='" + this->protocol_name.str() + "' >" << endl;

}

bool UdpSession::add(udp_hdr_t *udp){

//	Verifica se o arquivo de saida esta aberto ou nao, se nao estiver o abre

	if (!this->packets.is_open()){
		this->packets.open(this->filename.c_str(), ofstream::app | ofstream::ate);

		if ( !this->packets.is_open() ){
			cout << "O arquivo " << this->filename << " não pode ser aberto" << endl;
			return false;
		}
	}

//	Ajusta o curso dentro do texto para sobrescrever o fim da tag icmpsession, desta forma sempre colocamops os pacotes detro do <icmpsession></icmpsession>
	int end = this->packets.tellp();
	this->packets.seekp(end - 13);

//	Escreve os dados do pacote capturado
    this->packets << "<udp " <<
    	"source='"   << this->src_port_name.str()    <<
    	"' dest='" << this->dst_port_name.str()   <<
    	"' len='"  << dec << udp->len*4 <<
    	"' checksum='" << hex << ntohs(udp->check)  << "' ></udp>";

	this->packets.flush();
	this->packets.close();
	return true;
}

